Menu Général
REFERENCES DU LANGAGE VHDL


SOMMAIRE
Aggregates
 
Exit Statement
Library Clause
Procedures
Subtype Declaration
Alias Declaration
 
File Declaration
Literals
Process
Type Conversion
Architecture
Component Declaration
For Loop
Names
Qualified Expressions
Type Declaration
Arrays
Component Instantiation
Functions
Next Statement
Signal Declaration
Use Clause
Assert Statement
Configuration Declaration
Generate Statement
Null Statement 
Concurrent Signal Assignment
Variable Assignment
Attributes
Configuration Specification
Generics
Operators
Conditional Signal Assignment
Variable Declaration
Block Statement
 Constant Declaration
If Statement
Package
Selected Signal Assignment
Wait Statement
 Case Statement  Entity  
Package Body
Sequential Signal Assignment
While and Infinite Loop


Aggregatesretour en HAUT Un Aggregate est une expression qui peut être utilisée dans une entity, une architecture, un package ou un package body.

Syntaxe : (valeur_1, valeur_2, ...)

(item_1 => value_1, item_2 =>val_2, ...) Règles et Exemples :

Les Aggregates sont des groupements de valeurs formant des tableaux ou des enregistrements. La première forme ci-dessous est appelée association positionnelle, où les valeurs sont associées aux éléments de la gauche vers la droite.

signal Z_BUS : bit_vector (3 downto 0);

signal A_BIT, B_BIT, C_BIT, D_BIT : bit;

... Z_BUS <= (A_BIT, B_BIT, C_BIT, D_BIT);

Association équivalente : Z_BUS(3) <= A_BIT;

Z_BUS(2) <= B_BIT;

Z_BUS(1) <= C_BIT;

Z_BUS(0) <= D_BIT;
La deuxième forme est l’ association par noms, où les éléments sont explicitement référencés et où l’ordre ne compte pas. signal Z_BUS : bit_vector (3 downto 0);

signal A_BIT, B_BIT, C_BIT, D_BIT : bit;

Z_BUS <= (2 => B_BIT, 1 => C_BIT, 0 => D_BIT, 3 => A_BIT);

Dans l’association positionnelle, les éléments peuvent être groupés en utilisant le symbole | ou un intervalle. Le mot clé others peut être utilisé pour tout les éléments non encore mentionnés : signal B_BIT : bit;

signal BYTE : bit_vector (7 downto 0);

BYTE <= (7 => '1', 5 downto 1 => '1', 6 => B_BIT, others => '0');

L’assignation à un enregistrement complet doit être faite en utilisant un aggregate. Les associations par nom ou positionnelle peuvent être utilisées : type T_PACKET is record

BYTE_ID : std_ulogic;

PARITY : std_ulogic;

ADDRESS : integer range 0 to 3;

DATA : std_ulogic_vector(3 downto 0);

end record;

signal TX_DATA : T_PACKET;

TX_DATA <= ('1', '0', 2, "0101");

Un aggregate contenant seulement others peut affecter une valeur à tous les éléments d’un tableau, indépendamment de sa taille : type NIBBLE is array (3 downto 0) of std_ulogic;

type MEM is array (0 to 7) of NIBBLE;

variable MEM8X4: MEM := (others => "0000");

variable D_BUS : std_ulogic_vector(63 downto 0) := (others => 'Z');

Effets sur la synthèse

Les outils de synthèse ne supportent pas complètement l’association par nom. Ainsi, l’assignation d’enregistrement utilisant les aggregates n’est pas supportée.


Alias Declarationretour en HAUT Un Alias est une déclaration qui peut être utilisée dans une entity, une architecture, un package, unprocess, une procedure, une fonction ou un package body.

Syntaxe : alias nom_alias : type_alias is nom_objet;

Règles et Exemples

Un alias est un autre nom pour un objet existant (signal, variable ou constant). Il ne doit pas définir un nouvel objet :

alias SIGN : bit is DATA(31);alias BYTE_ID : bit is NET_DATA_IN(7); Les alias permettent de simplifier les références à des découpages complexes : use work.BV_ARITH.all;

alias OPERAND : bit_vector(1 downto 0) is CPU_BUFFER(LOW) (4 downto 3);

alias A : bit_vector(3 downto 0) is CPU_BUFFER(HIGH)(3 downto 0);

alias B : bit_vector(2 downto 0) is CPU_BUFFER(LOW) (2 downto 0);

...

CPU_DATA_TMP := (B & A) + OPERAND;

L’alias d’un tableau peut être indexé en sens contraire :

signal BUS_A : std_ulogic_vector(7 downto 0);

alias BIT_REV_A : std_ulogic_vector(0 to 7) is BUS_A;

Effets sur la synthèse

Les alias ne sont pas supportés par la plupart des outils de synthèse.


Architectureretour en HAUT Une Architecture est un élément de projet secondaire ( secondary design unit).

Syntaxe : architecture arch_name of entity_name is

declarations

begin

concurrent statements

end arch_name;

Règles et Exemples

Les déclarations peuvent être : type, subtype, signal, constant, file, alias, component, attribut, function, procedure ou configuration :

architecture TB of TB_CPU_IF is

component CPU_IF

port -- liste des entrées et sorties ...

end component;

signal CPU_DATA_VALID : std_ulogic;

signal CLK, RESET : std_ulogic := '0';

constant PERIOD : time := 10 ns;

constant MAX_SIM : time := 50 * PERIOD;

begin

-- instructions simultanées

end TB;

L’ordre des instructions simultanées (concurrent statements) n’est pas important ; le comportement est défini par les relations entre les données : architecture EX1 of CONC is

signal Z,A,B,C,D :integer;

begin

D <= A + B;

Z <= C + D;

end EX1;

Les éléments déclarés dans une architecture sont " visibles " dans tous les process ou block qu’elle contient.

Une architecture équivalente :

architecture EX2 of CONC is

signal Z,A,B,C,D :integer;

begin

Z <= C + D;

D <= A + B;

end EX2;

Une architecture peut contenir n’importe quel association d’instance de composant, de process ou d’autre instructions simultanées (concurrent statements) : architecture TEST of TB_DFF is

component DFF

port (CLK, D : in std_ulogic;

Q : out std_ulogic);

end component;

signal CLK, D, Q : std_ulogic := '0';

begin

UUT: DFF port map (CLK, D, Q);

CLK <= not (CLK) after 25 ns;

STIMULUS: process

begin

wait for 50 ns;

D <= '1';

wait for 100 ns;

D <= '0';

wait for 50 ns;

end process STIMULUS;

end TEST;

Une entité (entity) peut avoir plusieurs architectures. Celle qui est utilisée est précisée par la configuration.

Une Architecture ne peut pas être analysée à moins que l’entité à laquelle elle se réfère n’existe dans la librairie de projet (design library).

Effets sur la synthèse

Les architectures sont totalement supportées par les outils de synthèse dans la mesure ou les déclarations et les instructions quelles comportent soient compatibles avec la synthèse.


Arraysretour en HAUT Un Array (tableau) est une déclaration qui peut être utilisée dans une entity, une architecture, un package, un process, une procedure, une fonction.

Syntaxe : type nom_type is array (range) of type_element;

Règles et Exemples

Un array contient plusieurs éléments d’un même type. Lorsqu’un tableau est déclaré, il doit correspondre à un type tableau existant.

type NIBBLE is array (3 downto 0) of std_ulogic;

type RAM is array (0 to 31) of integer range 0 to 255;

signal A_BUS : NIBBLE;

signal RAM_0 : RAM;

La définition d’un type tableau peut être sans contrainte c’est à dire sans longueur définie. String, bit_vector et std_logic_vector sont ainsi définis. Un objet (signal, variable ou constant) de type tableau sans contrainte doit avoir un intervalle d’indice lorsqu’il est déclaré. type INT_ARRAY is array (integer range <>) of integer;

variable INT_TABLE: INT_ARRAY(0 to 9);

variable LOC_BUS : std_ulogic_vector(7 downto 0);

Les tableaux ayant des caractères comme éléments, comme string, bit_vector et std_logic_vector doivent être assignés en utilisant les doubles quotes. CONSTANT MSG_0: string := "Test 1 Terminé";

A_BUS <= "0000";

LOC_BUS := "10101010";

Les tableaux peuvent aussi être assignés en utilisant la concaténation (&), les aggregates, les découpages ou un mélange de ces possibilités. Par défaut, l’assignation est par position. A_BUS <= (A_BIT, B_BIT, C_BIT, D_BIT);

-- une assignation équivalante:

A_BUS <= A_BIT & B_BIT & C_BIT & D_BIT;

-- rotation de A_BUS vers la gauche:

A_BUS <= A_BUS(2 downto 0) & A_BUS(3);

Les tableaux de tableaux peuvent être déclarés (pour les mémoires, les tables de vecteurs, etc...) type NIBBLE is array (3 downto 0) of std_ulogic;

type MEM is array (0 to 7) of NIBBLE;

-- le type tableau de tableau

variable MEM8X4: MEM;

-- accession à tout le tableau:

MEM8X4 := ("0000","0001","0010","0011","0100","0101","0110","0111");

-- accéder à un "mot":

MEM8X4(5) := "0110";

-- accéder à un seul "bit":

MEM8X4(6) (0) := '0';

Les tableaux à plusieurs dimensions peuvent être déclarés : type T_2D is array (3 downto 0, 1 downto 0) of integer;

signal X_2D : T_2D;

X_2D <= ((0,0), (1,1), (2,2), (3,3));

X_2D(3,1) <= 4;

Effets sur la synthèse

La plupart des outils de synthèse acceptent les tableaux à une dimension.


Assert Statementretour en HAUT

Comme une instruction simultanée, une Assertion peut être utilisée dans une entity ou une architecture. Comme une instruction séquentielle, une Assertion peut être utilisée dans un process, une function ou une procedure.

Syntaxe : assert condition report chaîne_de_caractères severity niveau_de_sévérité;

Règles et Exemples

L’instruction Assert teste une condition booléenne. Si elle est fausse, elle affiche le message contenu dans la chaîne de caractère sur l’écran du simulateur :

assert (J /= C) report "J = C" severity note; Le niveau de sévérité peut être : note, warning, error ou failure. Le niveau failure provoque l’arrêt de la simulation :

assert not(OVERFLOW) report "Dépassement de capacité de l’accumulateur" severity failure;

Si la clause message est omise, un message par défaut est affiché. Le niveau de sévérité ainsi que le nom de l’élément de projet (design unit) contenant l’instruction assert sont affichés.

Si la clause de sévérité est omise, le niveau par défaut est error.

Une instruction simultanée assert teste continuellement la condition booléenne.

En utilisant le mot false comme condition on provoque l’affichage inconditionnel du message :

procedure PUT (signal STACK : inout T_STACK; signal POINTER: inout T_POINT;

signal ITEM : in T_DATA) is

begin

if (POINTER < 5) then

STACK(POINTER) <= ITEM;

POINTER <= POINTER + 1;

else assert false report "Dépassement de capacité de la pile" severity error;

end if;

end PUT;

Une erreur fonctionnelle ou une erreur temporelle peuvent être mise en évidence grâce à assert : CHECK_SETUP: process (CLK, D)

begin

if (CLK'event and CLK='1') then assert D'stable(SETUP_TIME)

report " Violation de Setup..." severity warning;

end if;

end process CHECK_SETUP;

Effets sur la synthèse

L’instruction assert n’est pas prise en compte par les outils de simulation.


Attributesretour en HAUT Un Attribute peut être utilisé dans une entité, une architecture, un package ou un package body.

Syntaxe : objet'nom_attribute

Règles et Exemples

Les attributes fournissent des informations supplémentaires sur : signal, variable, type ou componant. Certains attributes sont prédéfinis pour : type, array et signal.

Voici quelques attributes prédéfinis pour le type scalar, array avec contrainte.

Nom Definition

X'high La borne supérieure de X

X'low La borne inférieure de X

X'left La limite à gauche de X

X'right La limite à droite de X

Les attributes ci-dessous sont prédéfinis uniquement pour les arrays avec contrainte : Nom Definition

X'range L’intervalle de X

X'reverse_range L’intervalle de X à rebours

X'length X'high - X'low + 1 (entier)

Les attributes ci-dessous sont prédéfinis pour signal : Nom Definition

X'event Vrai lorsque X change (booléen)

X'active Vrai lorsque X est affecté (booléen)

X'last_event Lorsque X a fini d’évoluer (durée)

X'last_active Lorsque X a fini d’être affecté (durée)

X'last_value Précédente valeur de X (même type que X)

Les attributes ci-dessous permettent de créer un nouveau signal basé sur X : Nom Definition

X'delayed(T) X, retardé de T (même type que X)

X'stable(T) Vrai si X reste inchangé pendant une durée T (booléen)

X'quiet(T) Vrai si X n’est pas affecté pendant un durée T (booléen)

X'transaction "Toggles" lorsque X est affecté (bit)

Les attributes définis par l’utilisateur peuvent êtredéfinis. Ils n’affectent pas la simulation, mais permettent d’apporter des informations supplémentaires aux outils de synthèse : type IC_PACKAGE is (DIL, PLCC, PGA);

attribute PTYPE : IC_PACKAGE;

attribute PTYPE of U1: component is PLCC;

attribute PTYPE of U2: component is DIL;

Effets sur la synthèse

Les outils de synthèse usuels supportent les attributes ‘high, 'low, 'left, 'right, 'range, 'reverse_range, 'length et 'event. Certains outils supportent 'last_value et 'stable.


Block Statementretour en HAUT L’instruction Block est une instruction simultanée utilisée dans une architecture.

Syntaxe : label: block (condition_de_garde_optionnelle)

declarations

begin

instructions simultanées end block label;
Règles et Exemples

Le label est obligatoire :

CONTROL_LOGIC: block

begin

U1: CONTROLLER_A port map (CLK,X,Y,Z);

U2: CONTROLLER_A port map (CLK,A,B,C);

end block CONTROL_LOGIC; DATA_PATH: block

begin

U3: DATAPATH_A port map (BUS_A,BUS_B,BUS_C,Z);

U4: DATAPATH_B port map (BUS_A,BUS_C,BUS_D,C);

end block DATA_PATH;

Sans condition de garde, un block est associé avec les instructions simultanées d’une architecture. On peut déclarer des signaux, constantes, ... de façon locale. Les blocks peuvent contenir d’autres block et ainsi former une hiérarchie dans une architecture.Un block peut contenir toutes les déclarations admises pour les architectures. Ces déclarations ne sont visibles qu’à l’intérieur du block. Si une condition de garde est incluse le block devient un block de garde.

Effets sur la synthèse

Les blocks sans condition de garde sont " mis à plat " par les outils de synthèse.


Case Statementretour en HAUT L’instruction Case est une instruction séquentielle qui peut être utilisée dans un process, une function ou une procedure.

Syntaxe : case expression is

when choix1 => instructions séquentielles when choix2 => instructions séquentielles

end case;

Règles et Exemples

Tous les choix possibles doivent être inclus, à moins que la clause others ne soit utilisée comme dernier choix :

case SEL is

when "01" => Z <= A;

when "10" => Z <= B;

when others => Z <= 'X';

end case;

Un intervalle ou plusieurs possibilités peuvent être proposés : case INT_A is

when 0 => Z <= A;

when 1 to 3 => Z <= B;

when 4|6|8 => Z <= C;

when others => Z <= 'X';

end case;

Les choix ne doivent pas se recouvrir : case INT_A is

when 0 => Z <= A;

when 1 to 3 => Z <= B;

when 2|6|8 => Z <= C; ***

when others => Z <= 'X';

end case;

Un intervalle ne doit pas être utilisé avec le typevector : case VEC is

when "000" to "010" => Z <= A; ***

when "111" => Z <= B;

when others => Z <='X';

end case;

Effets sur la synthèse

L’instruction case est en général synthètisable.


Component declarationretour en HAUT La déclaration component peut être utilisée dans une architecture ou un package.

Syntaxe : component nom_du_composant

generic (liste_de_ generic);

port (list_des_E/S);

end component;
Règles et Exemples

La liste d’entrées et sortie doit définir le nom, le mode (direction) et le type de chaque entrée et sortie du composant :

component DEMIADD

port(A,B : in bit; SUM, CARRY : out bit); end component;

La déclaration de component ne définit pas la paire entity-architecture qui sera associé à chaque instance, ou les entrées et sorties de l’entity. Ceci est fait par la configuration.

Dans une architecture, les components doivent être déclarés avant l’instruction begin :

architecture STRUCTURE of ADD is

-- (Ici déclarations locale des signaux)

component PORTEOU

port (A,B : in bit; Z : out bit);

end component;

-- (Déclarations des autres components)

begin

-- Contenu de l’architecture

end STRUCTURE;

Un component déclaré dans un package est visible dans toute architecture qui utilise ce package et ne doit pas être déclaré de nouveau.

Les generics doivent être déclarés avant les ports.

component PARITY

generic (N : integer);

port (A : in std_ulogic_vector (N-1 downto 0);

ODD : out std_ulogic);

end component;

Effets sur la synthèse

Les outils de synthèse supporte les components.


Component Instantiationretour en HAUT L’instruction d’instanciation de composant est une instruction simultanée qui peut être utilisée dans une architecture.

Syntaxe : label-de_l’insatnce: nom_du_composant

generic map (liste_des_genrics_associés)

port map (liste_des_E/S_associées);

Règles et Exemples

Le label de l’instance est obligatoire. Le nom du composant doit correspondre au nom de la déclaration :

architecture STRUCT of INC is

signal X,Y,S,C : bit;

component DEMIADD

port(A,B : in bit;

SUM, CARRY : out bit);

end component;

begin

U1: DEMIADD port map (X,Y,S,C);

-- autres instructions

end STRUCT;

La liste d’association définit quel signal local doit être connecté aux entrées ou sorties du composants. La liste d’association ci-dessus est positionnelle, c’est à dire que les connections se font dans l’ordre où les entrées et sorties sont déclarées.

Une autre possibilité est l’association par nom, où les entrées et sorties sont explicitement référencées :

ADD1: DEMIADD port map( B => Y, A => X, SUM => S, CARRY => C); Les entrées ou sorties peuvent ne pas être connectées on utilise alors le mot clé open: ADD2: DEMIADD port map (B=>Y,A=>X,SUM=>S,CARRY=>open); Une instance de composant avec generics a son generic map déclaré avant le port map. U1 : PARITE

generic map ( N => 8)

port map ( A => DATA_BYTE, ODD => PARITY_BYTE);

Effets sur la synthèse

L’instanciation de composants est supportée par les outils de synthèse, generic map est ignoré.


Configuration Declarationretour en HAUT La déclaration de configuration est un élément de librairie primaire (primary library unit)

syntaxe : configuration nom_de_config of nom_d’entité is

for nom_d’architecture

for label_ d’instance: nom_de_composant

use entity

nom_lib.nom_entité(nom_arch);

for nom_arch

-- bas niveau de spécifications de configurations

...

end for;

end for;

end for;

end nom_de_config;

configuration nom_de_config of nom_d’entité is

for nom_d’architecture

for label_ d’instance: nom_de_composant

use configuration nom_lib.nom_cfg;

end for;

end for;

end nom_de_config;
Règles et Exemples

Avec la première forme de configuration de component ci-dessus, la totalité de la hiérarchie peut être configurée à partir d’une seule déclaration. La seconde forme ci-dessus est constituée d’un " arbre " de déclarations de configuration. En l’absence d’une configuration explicite les liens par défaut sont appliqués. Pour chaque instance de composant, une entité sera sélectionnée ; son nom, le nom de ses ports et le type des port correspondant à ceux de la déclaration de component.

Le mot clé all peut être utilisé pour se référer à toutes les instances d’un composant.

configuration CFG_ADD of ADD is

for STRUCTURE

for all : DEMIADD use entity work.DEMIADD(COMPORT);

end for;

end for;

end CFG_ADD;

Le mot clé others peut être utilisé pour se référer à toutes les instances d’un composant. Si les noms d’un port ne correspondent pas à la déclaration, port map peut y être: configuration CFG_ADD of ADD is

for STRUCTURE

for all : DEMIADD use entity work.HA(B)

port map(X => A, Y => B, S => SUM, C => CARRY);

end for;

end for;

end CFG_ADD;

Effets sur la synthèse

La configuration n’est en général pas supportée par les outils de synthèse.


Configuration Specificationretour en HAUT Une Specification de Configuration peut être utilisée dans une architecture.

Syntaxe : for label_d’instance: nom_du_composant use entity nom_lib.nom_entity(nom_arch);

for label_d’instance: nom_du_composant use configuration nom_lib.nom_config; Règles et Exemples

Pour utiliser une spécification de configuration, les components doivent être configurés à l’intérieur de l’architecture qui les instancie.

Architecture STR of XA is

componant DEMIADD port (A,B  in bit ; SUM, CARRY :out bit) ;

end component ;

componant ORGATE port (A,B : in bit ; Z :out bit) ;

end component ;

for U1 : DEMIADD use entity work.HA(BEHAVE) ;

for U1 : ORGATE use entity work.OG(BEHAVE) ;

begin

U1 : DEMIADD port map (A, B, S, C) ;

U2 : ORGATE port map (A,B,Y) ;

end STR ;

Le mot clé all peut être utilisé pour faire référence à toutes les instances d’un component.

For all : ADDI use entity work.ADDI(STRUCTURAL) ;

Le mot clé others peut être utilisé pour faire référence à toutes les instances non explicitement mentionnées.

Si les noms des ports d’une entity ne correspondent pas à la déclaration du component. Une assocoation de port map doit êtte incluse dans la configuration.

For all : DEMIADD use entity work.DEMIADD(BEHAV)

port map (X => A, Y => B, S => SUM, C => CARRY) ;

Effets sur la synthèse

Les configurations ne sont en général pas supportées par les outils de synthèse.


Constant Declarationretour en HAUT Une Constant Declaration peut être utilisée dans une entity, un package, un process, une architecture, une procedure ou une function.

Syntaxe : constant constant_name : type := value;

Règles et Exemples

constant BUS_WIDTH : integer := 8;

constant FOUR_ONES :std_logic_vector(3 downto 0):= "1111";

constant PERIOD : time := 10 ns;

constant MAX_SIM_TIME :time := 50 * PERIOD;

Les valeurs d’un tableau de constantes de types autres que string, bit_vector et std_logic_vector, doit être fixé en utilisant des aggregates.

type T_CLOCK_TIME is ARRAY(3 downto 0) of integer range 0 to 9;

constant TWELVE_O_CLOCK : T_CLOCK_TIME := (1,2,0,0);

Dans un package une constante doit être différée. Cela signifie que sa valeur est définie dans le package body. Sa valeur peut être modifiée en re-analysant seulement le package body:

package P is

constant C : integer;

end P;

package body P is

constant C : integer := 200;

end P;

Pourvues d’un type correct, les constantes peuvent être utilisées dans n’importe quelle expression. Elles peuvent être associées aux generics d’instance de component et passées dans les procedures:

process

type T_DATA is array (0 to 3) of bit_vector(7 downto 0);

constant DATA : T_DATA := ("00001000", "00010001", "00100010", "01000011");

begin

for I in DATA'range loop serialize_byte(DATA(I),DOUT);

end loop;

end process;

Effets sur la synthèse

Les constantes sont supportées pour la synthèse. 


Entityretour en HAUT Une Entity est une primary library unit.

Syntaxe : entity entity_name is generic (generic_list);

port (port_list);

end entity_name;

Règles et Exemples

La liste de port doit définir le nom, le mode (la direction) et le type de chaque port de l’entity:

entity DEMIADD is

port(A,B : in bit; SUM, CARRY : out bit);

end DEMIADD;

entity COUNTER is

port (CLK : in std_ulogic; RESET: in std_ulogic; Q : out integer range 0 to 15);

end COUNTER;

L’entité de plus haut niveau d’un modèle VHDL est usuellement "vide", c’est à dire qu’il n’a pas de ports. Son architecture est un "test bench" (banc de test): entity TB_DISPLAY is

end TB_DISPLAY;

architecture TEST of TB_DISPLAY is

-- signal declarations

-- component declaration(s)

begin

-- component instance(s)

-- test processes

end TEST;

Chaque port de l’entity se comporte comme un signal visible dans l’architecture(s) de l’entity. Le mode (c.a.d. la direction) de chaque port determine comment il doit être lu ou écrit dans l’architecture.
 
Mode 
Lit dans une Arch?
Ecrit dans une Arch?
in
Yes
No
out
No
Yes
inout
Yes
Yes
buffer
Yes
Yes

Si une entity a des generics, ils doivent être déclarés avant les ports. Ils ne doivent pas avoir de mode, par définition ils ne peuvent que passer des informations dans l’entity:

entity AN2_GENERIC is

generic (DELAY: time := 1.0 ns);

port (A,B : in std_ulogic; Z : out std_ulogic);

end AN2_GENERIC;

Une entity peut aussi contenir des déclarations. Les éléments déclarés sont visibles dans l’architecture(s) de entity.

Effets sur la synthèse

Les Entity declarations sont supportées pour la synthèse.


Exit Statementretour en HAUT Exit est une instruction sequentielle qui peut être utilisée dans loop, for loop, ou while loop.

Syntaxe : exit;

exit loop_label;

exit loop_label when condition;

Règles et Exemples

L’instruction exit est utilisée pour terminer une boucle infinie :

for I in 0 to 7 loop if FINISH_LOOP_EARLY = '1' then exit; else A_BUS <= TABLE(I); wait for 5 ns;

end if;

end loop;

L’instruction exit peut tester une condition booléenne utilisant le mot clé when: process (A)

variable I : integer range 0 to 4;

begin

Z <= "0000";

I := 0;

loop exit when I = 4;

if (A = I) then Z(I) <= '1';

end if;

I := I + 1;

end loop;

end process;

Pour une instruction exit dans un ensemble de boucle un label peut être utilisé pour indiquer quelle boucle doit être abandonnée. Par défaut c’est la boucle la plus interne: L1: for I in 0 to 7 loop

L2: for J in 0 to 7 loop

exit L1 when QUIT_BOTH_LOOPS = '1';

exit when QUIT_INNER_LOOP = '1';

-- other statements

end loop L2;

end loop L1;

Effets sur la synthèse

L’instruction exit est supportée par certains outils de synthèse.


File Declarationretour en HAUT Une File Declaration peut être utilisée dans un package, un process, une architecture, une procedure ou une function.

Syntaxe : file logical_name : file_type is mode "file_name";

Règles et Exemples

Habituellement on utilise des fichiers de type texte, car ils sont portables sur différents simulateurs VHDL. Le mode du fichier fait référence à la direction du flot de données, il peut être in (c.a.d. fichier à lecture seule) ou out (c.a.d fichier en écriture):

use std.textio.all;

package REF_PACK is

file INFILE : text is in "in.dat";

file OUTFILE: text is out "out.dat";

end REF_PACK;

Les fichiers textes peuvent être lus en utilisant les sous programmes endfile, readline et read définis dans le packagestd.textio: READ_FILE: process

variable VEC_LINE : line;

variable VEC_VAR : bit_vector(0 to 7);

file VEC_FILE : text is in "stim.vec";

begin

while not endfile(VEC_FILE) loop

readline (VEC_FILE, VEC_LINE);

read (VEC_LINE, VEC_VAR);

A_BUS <= VEC_VAR;

wait for 10 ns;

end loop;

wait;

end process READ_FILE;

Le package doit être rendu visible par la clause: use std.textio.all;

Les fichiers textes sont écrits en utilisant les sous programmes write et writeline, définis dans le packagestd.textio:

WRITE_FILE: process (CLK)

variable VEC_LINE : line;

file VEC_FILE : text is out "results";

begin

-- strobe OUT_DATA on falling edges of CLK and write value out to file

if CLK='0' then

write (VEC_LINE, OUT_DATA);

writeline (VEC_FILE, VEC_LINE);

end if;

end process WRITE_FILE;

Effets sur la synthèse

La déclaration de fichier n’est pas supportée par les outils de synthèse.


For Loopretour en HAUT For Loop est une instruction séquentielle qui peut être utilisée dans un process, une function ou une procedure.

Syntaxe : optional_label: for parameter in rangeloop

sequential statements

end loop optional_label;

Règles et Exemples

L’instruction for loop definie les paramètres d’une boucle dans l’intervalle spécifié. Par exemple, l’intervalle 0 to 3 implique le type integer:

process (A)

begin

Z <= "0000";

for I in 0 to 3 loop if (A = I) then Z(I) <= '1';

end if;

end loop;

end process;

Les attributes tels que 'low, 'high et 'range peuvent être utiliser pour définir les itérations de la boucle for loop: process (A)

variable TMP : std_ulogic;

begin

TMP := '0';

for I in A'low to A'high loop TMP := TMP xor A(I);

end loop;

ODD <= TMP;

end process;

L’intervalle peut être de n’importe quel type discret, par exemple de type énuméré: type PRIMARY is (RED, GREEN, BLUE);

type COLOUR is ARRAY (PRIMARY) of integer range 0 to 255;

signal VIDEO: COLOUR;

signal V_BUS: INTEGER range 0 to 255;

-- other statements

MUX: process

begin

for SEL in PRIMARY loop

V_BUS <= VIDEO(SEL);

wait for 10 ns;

end loop;

end process MUX;

Les paramètres de la boucle ne doivent pas être déclarés : ils sont implictement déclarés dans la boucle. Ils ne doivent pas être modifiés dans la boucle : for I in 1 to 10 loop

if (REPEAT ='1') then I:= I-1; --

end if;

end loop;

Effets sur la synthèse

L’instruction for loop est supportée par les outils de synthèse à condition que:

(1) l’indice de boucle soit statique (c.a.d le nombre d’itération est pré défini), et (2) la boucle ne contienne pas d’instruction wait.


Functionsretour en HAUT Une Function est une déclaration qui peut être utilisée dans un package, une entity, une architecture, un process, une procedure ou une function.

Syntaxe : function function_name (parameter_list) return type is

declarations

begin

sequential statements

end function_name;

Règles et Exemples

Une function ne peut avoir que des paramètres d’entrée, le mode (direction) n’est pas spécifié:

function BOOL_TO_SL(X : boolean) return std_ulogic is

begin

if X then return '1';

else return '0';

end if;

end BOOL_TO_SL;

On peut déclarer des variables locales dans une function. Elle ne mémorise pas ses valeurs entre deux appels succéssifs, mais les réinitialise à chaque appel : function PARITY (X : std_ulogic_vector) return std_ulogic is

variable TMP : std_ulogic := '0';

begin

for J in X'range loop TMP := TMP xor X(J);

end loop; -- works for any size X

return TMP;

end PARITY;

Une function peut contenir n’importe quelle instruction séquentielle hormis une assignation de signal et l’instruction wait.

Une function de type-conversion peut être appelée dans le port map, pour associer le port type au signal type. Si une function est définie dans un package, son corps (ses instuctions) doit être placé dans le package body :

package REF_PACK is

function PARITY (X : bit_vector) return bit;

end REF_PACK;

package body REF_PACK is

function PARITY (X : bit_vector) return bit is

begin

-- function code

end PARITY;

end REF_PACK;

Une function est appelée comme une expression, dans n’importe quelle instruction simultanée ou séquentielle : architecture FUNCTIONS of PAR is

begin

PARITY_BYTE <= PARITY(DATA_BYTE);

PARITY_WORD <= PARITY(DATA_WORD);

end FUNCTIONS;

Effets sur la synthèse

Les functions définies par l’utilisateurs sont supportées par les outils de synthèse. 


Generate Statementretour en HAUT Generate est une instruction simultanée utilisée dans une architecture.

Syntaxe : label: for parameter in range generate

concurrent statements

end generate label;

Règles et Exemples

L’instruction for...generate est généralement utilisée pour instancier des "arrays" de components. Le paramètre de generate peut être utiliser pour indexer les signaux associés aux component ports:

architecture GEN of REG_BANK is

component REG

port(D,CLK,RESET : in std_ulogic;

Q : out std_ulogic);

end component;

begin

GEN_REG: for I in 0 to 3 generate

REGX : REG port map(DIN(I), CLK, RESET, DOUT(I));

end generate GEN_REG;

end GEN;

Un label est obligatoire avec l’instruction generate.

Les labels d’instance dans une instruction generate n’ont pas besoin d’être indéxés:

REGX(I): -- L’instruction for ... generate est particulièrement intéressante lorsqu’elle est utilisée avce des generics de type integer. L’instruction for ... generate peut être imbriquée pour créer des tableaux d’instances à deux dimension. Une autre forme de generate est l’instruction if ... generate. Elle est utilisée dans une instruction for...generate, pour tenir compte des irrégularités. Par exemple , un ripple-carry adder sans retenue en entrée: architecture GEN of RIPPLE is

component FULLADD port (A,B,CIN : in bit; SUM, CARRY : out bit);

end component;

component HALFADD port(A,B : in bit; SUM, CARRY : out bit);

end component;

signal C : bit_vector(0 to 7);

begin

GEN_ADD: for I in 0 to 7 generate

LOWER_BIT: if I=0 generate U0: HALFADD port map (A(I),B(I),S(I),C(I));

end generate LOWER_BIT;

UPPER_BITS: if I>0 generate UX: FULLADD port map (A(I),B(I),C(I-1),S(I),C(I));

end generate UPPER_BITS;

end generate GEN_ADD;

COUT <= C(7);

end GEN;

Effets sur la synthèse

Les instructions generate sont supportées par les outils de synthèse. 


Genericsretour en HAUT Un Generic est une déclaration qui peut être utilisée dans une entity ou un component

Syntaxe : entity entity_name is

generic (generic list);

port (port list);

end entity_name;

component component_name

generic (generic_list);

port (port_list);

end component;

instance_label: component_name

generic map (generic_association_list)

port map (port_association_list);

Règles et Exemples

Les generics servent à passer les informations spécifques d’une instance vers une entity. Elles ne doivent pas avoir de mode (direction):

entity PARITY is

generic (N : integer);

port (A : in std_ulogic_vector (N-1 downto 0); ODD : out std_ulogic);

end PARITY;

Dans les déclarations de component, les generics sont aussi déclarés avant les ports: component PARITY

generic (N : integer);

port (A : in std_ulogic_vector (N-1 downto 0); ODD : out std_ulogic);

end component;

Une instance d’un component avec generics, posséde un generic map déclaré avant le port map (remarque: il n’y a pas de point virgule entre eux!). U1: PARITY

generic map (N => 8)

port map (A => DATA_BYTE, ODD => PARITY_BYTE);

En déclarant des generics de type time, des delais peuvent être programmés. entity AN2_GENERIC is

generic (DELAY: time := 1.0 ns);

port (A,B : in std_ulogic; Z : out std_ulogic);

end AN2_GENERIC;

architecture BEH of AN2_GENERIC is

begin

Z <= A and B after DELAY;

end A;

Effets sur la synthèse

Habituellement, seuls les generics de type integer sont supportés.


If Statementretour en HAUT If est une instruction séquentielle qui peut être utilisée dans un process, une function ou unr procedure.

Syntaxe : if condition_1 then sequential statements

elsif condition_2 then sequential statements else sequential statements end if; Règles et Exemples if (X = 5) and (Y = 9) then Z <= A; elsif (X >= 5) then Z <= B; else Z <= C; end if; Les clauses elsif et else sont optionnelles. Le process suivant modélise un verrou transparant: process (EN, D)

begin

if (EN = '1') then Q <= D;

end if;

end process;

--A condition is any boolean expression:

process (ALARM_TIME, CURRENT_TIME)

variable AL_EQ_CUR: boolean;

begin

AL_EQ_CUR := (ALARM_TIME=CURRENT_TIME);

if AL_EQ_CUR then SOUND_ALARM <= '1';

else SOUND_ALARM <= '0';

end if;

end process;

Une instruction if doit être utilisée pour générer des registres actifs sur front dans un process réceptif à un signal d’horloge. Un reset asynchrone peut aussi être modéliser: process(CLK, RESET)

begin

if RESET = '1' then COUNT <= 0;

elsif CLK'event and CLK='1' then

if (COUNT >= 9) then COUNT <= 0;

else COUNT <= COUNT + 1;

end if;

end if;

end process;

L’instruction if peut être utilisée pour spécifier des assignations conditionnelles ou des transitions d’états dans les machines à nombres d’états finis: case READ_CPU_STATE is

when WAITING =>

if CPU_DATA_VALID = '1' then

CPU_DATA_READ <= '1';

READ_CPU_STATE <= DATA1;

end if;

when DATA1 =>

-- other branches of thecase statement

end case;

Effets sur la synthèse

L’instruction if est généralement synthètisable.


Library Clauseretour en HAUT La clause Library est une clause de contexte qui peut être utilisée dans une entity, un package ou une configuration.

Syntaxe : library library_name, another_library_name;

Règles et Exemples

La clause library doit apparaître avant le début du design unit:

library IEEE;

use IEEE.STD_LOGIC_1164.all;

entity WIDGET is-- etc.

end WIDGET;

La clause library n’est valide que pour le design unit qui la suit immédiatement.

Lorsque plusieurs primary design units, dans le même fichier, utilisent une même library, la clause library doit être répétée avant chaque unit.

Les librairies work et std n’ont pas à être déclarées. Chaque unit est implicitement par :

library WORK;

library STD;

use STD.STANDARD.all;

Effets sur la synthèse

La clause library est ignorée par les outils de synthèse.


Literalsretour en HAUT Les Literals sont utilisés dans les expressions.

Syntaxe : voir les exemples

Règles et Exemples

Les literals numérique avec un point décimalsont considérés comme des réels, et sans point décimal comme des entiers :

constant FREEZE : integer := 32;

constant TEMP : real := 32.0;

Les literals numérique peuvent être représentés dans n’importe quelle base de 2 à 16. Il peuvent aussi être scindés en utilisant le caractère souligné :

A_INT <= 16#FF#;

B_INT <= 2#1010_1010#;

MONEY := 1_000_000.0;

Les nombres réels peuvent s’écrire sous la forme mantisse, exposant:

FACTOR := 2.2E-6;

Les literals de type time (ou d’un autre type physique) doit avoir une unité. Le symbole de l’unité doit être précédé d’un espace:

constant DEL1 :time := 10 ns;

constant DEL2 :time := 2.27 us;

Les literals de type énuméré doivent être soit des caractères soit des identificateurs: type MY_LOGIC is ('X','0','1','Z');

type T_STATE is (IDLE, READ, END_CYC);

signal CLK : MY_LOGIC := '0';

signal STATE : T_STATE := IDLE;

Les literals pour les tableaux de caractères, comme string, bit_vector et std_logic_vector sont placés entre doubles quotes: constant FLAG :bit_vector(0 to 7) := "11111111";

constant MSG : string := "Hello";

Les literals Bit_vector doivent être exprimés en binaire (par défaut), octal ou hexa. Ils peuvent aussi contenir des caractères souligné. Cette forme peut être aussi utilisée pour les literals std_logic_vector: BIT_8_BUS <= B"1111_1111";

BIT_9_BUS <= O"353";

BIT_16_BUS <= X"AA55";

Des caractères non imprimables peuvent être inclus dans une chaîne : constant TWO_LINE_MSG : string := "Hello" & CR & "World"; Effets sur la synthèse

Les literals sont supportés par les outils de synthèse, s’ils appartiennent à un type acceptable. 


Namesretour en HAUT Les noms (ou identificateurs) peuvent être utilisés dans une entity, une architecture, un package, un package body, ou un configuration.

Syntaxe : voir les exemples

Règles et Exemples

Les noms (ou identificateurs) sont constitués de lettres, chiffres et souligné (underscore):

architecture RTL of UNIT_34 is

signal SOUND_ALARM : std_ulogic;

La casse (majuscule ou minuscule) n’est pas significative, les exemples suivants sont équivalants: An_Example_Name

AN_EXAMPLE_NAME

an_example_name

Les noms doivent commencer par une lettre: signal 16_BIT_BUS : integer; --

signal _BUS_16_BIT_ : integer; --

signal BUS_16_BIT : integer; --

Les noms peuvent avoir n’importe quelle longueur.

Aucun mot clé du langage VHDL (signal, bus, component, etc.) ne peut être utilisé comme nom.

Effets sur la synthèse

Les noms légaux sont supportés par les outils de synthèse. Certains tronquent les noms trop longs.


Next Statementretour en HAUT L’instruction Next est sequentielle elle est utilisée dans une boucle loop, for loop ou while loop.

Syntaxe : next;

next loop_label;

next loop_label when condition;

Règles et Exemples

L’instruction Next permet de terminer prématurément une boucle :

for I in 0 to 7 loop

if SKIP = '1' then next;

else N_BUS <= TABLE(I); wait for 5 ns; end if;

end loop;

L’instruction Next peut tester une condition booléenne en utilisant le mot clé when: process (A)

begin

Z <= "0000";

for I in 0 to 3 loop

next when A /= I;

Z(I) <= '1';

end loop;

end process;

Lorsqu’on utilise l’instruction next dans des boucles imbriquées, un label doit être utilisé pour indiquer le niveau d’itération. Par défaut c’est la boucle la plus interne. READ_BUS: process

begin

RESETLOOP: loop

VALID_CHECK: while (CPU_DATA_VALID /= '1') loop

wait until rising_edge(CLK) or RESET = '1';

next RESETLOOP when RESET='1';

end loop VALID_CHECK;

CPU_DATA_READ <= '1';

wait until rising_edge(CLK);

LOCAL_BUFFER <= DATA_BUS;

wait until rising_edge(CLK);

CPU_DATA_READ <= '0';

end loop RESETLOOP;

end process READ_BUS;

Effets sur la synthèse

L’instruction next est supportée par certains outils de synthèse.


Null Statementretour en HAUT Null est une instruction séquentielle utilisée dans un process, une function ou un procedure.

Syntaxe : null;

Règles et Exemples

Null est une instruction qui ne " fait rien ".

case ENCRYPTION is

when "00" => CPU_DATA_TMP := (B & A) - OPERAND;

when "01" => CPU_DATA_TMP := (B & A) + OPERAND;

when "10" => CPU_DATA_TMP := (A & B) - OPERAND;

when "11" => CPU_DATA_TMP := (A & B) + OPERAND;

when others => null;

end case;

Effets sur la synthèse

L’instruction null est supportée par les outils de synthèse.


Operatorsretour en HAUT Un Operator est utilisé dans une Expression.

Syntaxe : voir les exemples

Règles et Exemples

Les opérateurs logiques sont pré définis pour les types bit, boolean, bit_vector, linear arrays of boolean, std_logic et std_logic_vector. Ils renvoient une valeur de même type:

and, or, nand, nor, xor, not Les opérateurs égalité et non égalité sont pré défini pour tout les types, ils renvoient un boolean : = -- égal à /= -- non égal à Les opérateurs relationnels sont pré définis pour tout les types scalaires, et tout les types de tableau de dimension 1. Ils renvoient un boolean: < -- less than

> -- greater than

<= -- less than or equal to

>= -- greater than or equal to

Pour les tableaux de différentes longueurs, les opérateurs relationnels pr é définis alignent à gauche les éléments, et comparent les positions correspondantes. Cela peut donner des résultats inattendus: constant ARR1 :bit_vector := "0011";

constant ARR2 :bit_vector := "01";

-- (ARR1 < ARR2) will return true

L’opérateurs & est utilisé pour concatener les tableaux ou ajouter des éléments à un tableau:

Z_BUS(1 downto 0) <= '0' & B_BIT;

BYTE <= A_BUS & B_BUS;

L’addition, la soustraction, la multiplication et la division dont définis pour les types integer et real. Les deux opérandes doivent être de même type, le résultat sera du même type: signal INT1, INT2: integer := 0;

signal REAL1, REAL2: real := 6.7;

INT1 <= INT1 + 3;

REAL1 <= REAL2 - 2.2;

INT2 <= INT1 * REAL1; --

INT2 <= INT1 * INTEGER(REAL1);

REAL2 <= REAL1 / 42.3;

Les autres opérateurs numériques sont exponentiation (**), valeur absolue (abs), modulo (mod), et reste de la division (rem).

Effets sur la synthèse

La plupart des opérateurs sont synthèsisables.


Packageretour en HAUT Un Package est un primary library unit.

Syntaxe : package package_name is

declarations

end package_name;

Règles et Exemples

Les déclarations sont typiquement les suivantes: type, subtype, constant, file, alias, component, attribute, function, procedure:

package DEMO_PACK is

constant SOME_FLAG : bit_vector := "11111111";

type STATE is (RESET,IDLE,ACKA);

component HALFADD

port(A,B : in bit; SUM,CARRY : out bit);

end component;

end DEMO_PACK;

Les éléments déclarés dans un package sont visible via la clause use. Supposons que DEMO_PACK soit analysé dans la librairie work: use work.DEMO_PACK.all;

entity DEMO is

port (Z: out bit_vector(7 downto 0));

end DEMO;

architecture BEHAVE of DEMO is

begin

Z <= SOME_FLAG;

end BEHAVE;

Lorsqu’une procedure ou une function est déclarée dans un package, son corps doit se trouver dans le package body.

Une constante déclarée dans un package doit être différée. Cela signifie que sa valeur sera définie dans le package body. La valeur peut être modifiée en re-analysant le seul package body:

package P is

constant C : integer;

end P;

package body P is

constant C : integer := 200;

end P;

Effets sur la synthèse

Les Packages sont supportés par les outils de synthèse.

Les déclarations synthésisable et non-synthésisable sont placées dans des packages différents



  Package Body Un Package Body est un secondary library unit.

Syntaxe : package body package_name is

declarations

deferred constant declarations

subprogram bodies

end package_name;

Règles et Exemples

Lorsqu’une procedure ou une function est déclarée dans un package, son corps doit être placé dans le package body:

package REF_PACK is

procedure PARITY

(signal X : in bit_vector;

signal Y : out bit);

end REF_PACK;

package body REF_PACK is

procedure PARITY

(signal X : in bit_vector;

signal Y : out bit) is

begin

-- procedure code

end PARITY;

end REF_PACK;

Les déclarations faites dans un package body ne sont pas visible en dehors. Les déclarations peuvent être: type, subtype, constant, file, alias, attribute, function, procedure.

Une constante déclarée dans un package doit être différée. Cela signifie que sa valeur sera définie dans le package body. La valeur peut être modifiée en re-analysant le seul package body:

package P is

constant C : integer;

end P;

package body P is

constant C : integer := 200;

end P;

Un package body ne peut être analysé à moins qu’un package correspondant n’existe dans la même design library.

Chaque package ne peut avoir qu’un seul body.

Effets sur la synthèse

Les Package bodies sont supportés par les outils de synthèse.

Le package body doit se trouver dans le même fichier que le package.


Proceduresretour en HAUT Une Procedure est un déclaration qui s’utilise dans un package, une entity, une architecture, un process, une procedure ou une function.

Syntaxe : procedure procedure_name (parameter_list) is

declarations

begin

sequential statements

end procedure_name;

Règles et Exemples

Les procedures ont des paramètres de mode in, out ou inout. Ils peuvent être signal, variable ou constant. Par défaut un paramètre in est de type constant . Out et inout est de type variable.

procedure DISPLAY_MUX

(ALARM_TIME, CURRENT_TIME : in digit;

SHOW_A : in std_ulogic;

signal DISPLAY_TIME : out digit) is

begin

if (SHOW_A = '1') then DISPLAY_TIME <= ALARM_TIME;

else DISPLAY_TIME <= CURRENT_TIME;

end if;

end DISPLAY_MUX;

Les procedures peuvent être appelées de façon simultanée (concurrent) ou sequentielle. Une procedure simultanée s’execute chaque fois que ces paramètres in ou inout changent: architecture SUBPROG of DISP_MUX is

...

begin

DISPLAY_MUX (ALARM_TIME, CURRENT_TIME, SHOW_A, DISPLAY_TIME);

end SUBPROG;

Une procedure peut déclareer des variables locales. Elles ne conservent pas leurs valeurs mais sont initialisées à chaque appel: procedure PARITY

(signal X : in std_ulogic_vector;

signal Y : out std_ulogic) is

variable TMP : std_ulogic := '0';

begin

for J in X'range loop TMP := TMP xor X(J);

end loop; -- works for any size X

Y <= TMP;

end PARITY;

Une procedure peut contenir des instructions wait, à moins quelle ne soit appelée par un process avec une sensitivity list, ou par une function.

Si une procedure est définie dans un package, son corps doit être placé dans le package body:

package REF_PACK is

procedure PARITY

(signal X : in std_logic_vector;

signal Y : out std_logic);

end REF_PACK;

package body REF_PACK is

procedure PARITY

(signal X : in std_logic_vector;

signal Y : out std_logic) is

begin

-- procedure code

end PARITY;

end REF_PACK;

Effets sur la synthèse

Les procedures sont supportées par les outils de synthèse. Elles ne doivent pas contenir d’instruction wait.


Processretour en HAUT Un Process est une Instruction simultanée (Concurrent Statement) utilisée dans une architecture.

Syntaxe : optional_label: process (optional sensitivity list)

declarations

begin sequential statements end process optional_label; Règles et Exemples

La sensitivity list est une liste de signaux. Un changement d’une ou plusieurs des valeurs des signaux provoque l’activation du process:

process (ALARM_TIME, CURRENT_TIME)

begin

if (ALARM_TIME = CURRENT_TIME) then SOUND_ALARM <= '1';

else SOUND_ALARM <= '0';

end if;

end process;

Autrement, l’activation et la suspension du process est contrôlée par l’instruction wait: process

begin

if (ALARM_TIME = CURRENT_TIME) then SOUND_ALARM <= '1';

else SOUND_ALARM <= '0';

end if;

wait on ALARM_TIME, CURRENT_TIME;

end process;

Un process ne peut avoir à la fois une sensitivity list et des instructions wait.

Un process peut contenir n’importe quelle instruction séquentielle.

Effets sur la synthèse

Les Processes sont synthésisable, pourvu qu’ils respectent certaines formes:

Un "clocked process" doit avoir soit une instruction wait ou une sensitivity list. Pour un tel process, des registres sont implémentés à chaque assignation de signal:

WAIT_PROC: process

begin

wait until CLK'event and CLK='1';

Q1 <= D1;

end process;

SENSE_PROC: process (CLK)

begin

if CLK'event and CLK='1' then Q2 <= D2;

end if;

end process;

Un "combinational process" doit avoir une sensitivity list contenant tout les signaux lus (entrées), et doit mettre à jour ses sorties : process (A, B, SEL)

begin

Z <= B;

if SEL='1' then Z <= A;

end if;

end process;



  Qualified Expressionsretour en HAUT Les Qualified Expressions sont des Expressions. Qui sont utilisées dans une entity, une architecture, un package ou un package body.

Syntaxe : type'(expression)

Règles et Exemples

Une expression qualifiée est un expression avec un type clairement explicité.

string'("0010")

bit_vector'("0010")

std_logic_vector'("0010")

Une expression qualifiée peut être nécessaire pour l’appelle de functions ou de procedures. architecture OVER of A is

signal P_STD : std_logic;

signal P_BIT : bit;

function PARITY (X : bit_vector) return bit is

begin

-- function code

end PARITY;

function PARITY (X : std_logic_vector) return std_logic is

begin

-- function code

end PARITY;

begin

P_BIT <=PARITY(bit_vector'("00100"));

P_STD <= PARITY(std_logic_vector'("10101"));

end OVER;

Une expression qualifiée peut être nécessaire pour certains aggregates ou tableaux: entity CONCAT is

port(A,B : in std_ulogic;

VALUE: out integer range 0 to 9);

end CONCAT;

architecture BEHAVIOURAL of CONCAT is

subtype T_2 is std_ulogic_vector(1 downto 0);

begin

process(A,B)

begin

case T_2'(A & B) is

when "00" => VALUE <= 0;

when "01" => VALUE <= 1;

when "10" => VALUE <= 2;

when "11" => VALUE <= 3;

when others => VALUE <= 9;

end case;

end process;

end BEHAVIOURAL;

Effets sur la synthèse

Les expressions qualifiése sont supportées par les outils de synthèse.


Signal Declarationretour en HAUT Une Déclaration de Signal est une déclaration utilisée dans une architecture.

Syntaxe : signal signal_name : type;

signal signal_name : type := initial_value; Règles et Exemples signal SUM, CARRY1, CARRY2 : bit;

signal COUNT : integer range 0 to 15;

signal CLK, RESET : std_ulogic := '0';

signal ALARM_TIME : T_CLOCK_TIME := (1,2,0,0);

signal CONDITION : boolean := false;

Pendant la complilation, chaque signal est initialisé. Si le signal n’est pas explicitement initialisé, il prendra la plus petite valeur du type déclaré ('left): signal I : integer range 0 to 3;

-- I will initialise to 0

signal X : std_logic;

-- X will initialise to 'U'

A signal which is driven by more than one process, concurrent statement or component instance must be declared with a resolved type, e.g. std_logic or std_logic_vector: architecture COND of TRI_STATE is

signal TRI_BIT: std_logic;

begin

TRI_BIT <= BIT_1 when EN_1 = '1' else 'Z';

TRI_BIT <= BIT_2 when EN_2 = '1' else 'Z';

end COND;

Les signaux ne doivent pas être déclarés dans un process ou un subprogram .

Les ports déclarés dans une entity sont accessibles comme signaux dans l’architecture(s) associée et n’ont pas besoin d’être re-déclaré.

Un signal de type résolu doit être déclaré comme signal résolu

signal signal_name : resolved_type signal_kind;

Le mot clé "signal kind" doit être un registre ou un bus. Les siganux résolus gardés associés à un registre kind mémorisent leurs valeurs lorsque la source est déconnectée, alors que les signaux associés a un bus kind comptent sur la fonction de résolution pour fournir la valeur de sortie.

Effets sur la synthèse

Les signaux sont accéptés en synthèse.

Le type signal kind pour un registre ou un bus est ignoré.

La plupart des outils reconnaissent les types std_logic_1164.


Concurrent Signal Assignmentretour en HAUT Un Concurrent Signal Assignment est une forme d’instruction simultanée, utilisable dans une architecture.

Syntaxe : signal_name <= expression;

signal_name <= expression after delay; Règles et Exemples

Le concurrent signal assignment assigne une nouvelle valeur au signal cible chaque fois qu’un des signaux situés à droite du symbole <= change:

architecture CONC of HA is

begin

SUM <= A xor B;

CARRY <= A and B;

end CONC;

Les assignations simultanées sont équivanlentes au process suivant : architecture SEQ of HA is

begin

process (A,B)

begin

SUM <= A xor B;

CARRY <= A and B;

end process;

end SEQ;

On peut spécifier un délai: architecture DELAYS of X is

constant PERIOD : time := 10 ns;

begin

SUM <= A xor B after 5 ns;

CARRY <= A and B after 3 ns;

CLK <= not CLK after PERIOD/2;

end DELAYS;

Le model de délai par défaut est inertial. Cela signifie que les impulsions plus courtes que le délai ne sont pas propagées. L’alternative est le délai transport, qui propage toutes les transitions: architecture TRANS of BUFF is

constant DELAY : time := 10 ns;

begin

O_PIN <= transport I_PIN after DELAY;

end TRANS;

PlusieuRs assignations simultanées au même signal implique plusieurs sources (drivers). Un signal qui est la cible de plusieurs concurrent signal assignments doit être de type résolu, par exemple std_logic, std_logic_vector.

Effets sur la synthèse

Les concurrent signal assignments sont en général synthésisable, providing they use types and operators acceptable to the synthesis tool.

Un signal assigné par des instructions simultanées sera synthétisé par de la logique combinationatoire. Les délais sont ignorés.


Conditional Signal Assignmentretour en HAUT Un Conditional Signal Assignment est une forme d’instruction simultanée, utilisable dans une architecture.

Syntaxe : signal_name <= expression_1 when condition_1

else expression_2 when condition_2 else expression_3 ; Règles et Exemples

Chaque condition est une expression booléenne:

architecture COND of BRANCH is

begin

Z <= A when X > 5 else

B when X < 5 else C;

end COND;

Les conditions peuvent se recouvrir, comme pour l’instruction if. L’expression correspondant à la première condition " vraie " est assignée: architecture COND of BRANCH is

begin

Z <= A when X = 5 else

B when X < 10 else C;

end COND;

Il doit y avoir un dernier else inconditionnel: architecture COND of WRONG is

begin

Z <= A when X > 5; --

end COND;

Les expressions peuvent être associées à des délais. Le mode de delai Transport doit être spécifié.

Les conditional signal assignments peuvent être utilisés pour définir des buffers trois états, en utilisant les types std_logic et std_logic_vector. Remarquez l’utilisation de l’aggregate pour un bus:

architecture COND of TRI_STATE is

signal TRI_BIT: std_logic;

signal TRI_BUS: std_logic_vector(0 to 7);

begin

TRI_BIT <= BIT_1 when EN_1 = '1' else 'Z';

TRI_BUS <= BUS_1 when EN_2 = '1' else (others => 'Z');

end COND;

Effets sur la synthèse

les conditional signal assignments sont synthésisables.

Une assignation à 'Z' will génére une source 3-états.


Selected Signal Assignmentretour en HAUT Le Selected Signal Assignment est une forme d’instruction simultanée, utilisable dans une architecture.

Syntaxe : with expression select

signal_name <= expression_1 when choice_1 , expression_2 when choice_2 ; Règles et Exemples

Les règles sont les mêmes que pour l’instruction the case, c’est à dire que tout les choixdoivent être présents à moins que la clause others n’apparaîsse en dernier choix:

architecture SEL of BRANCH is

begin

with CMD select

Z <= B when "00",

C when "01",

A when others;

end SEL;

Un intervalle peut être spécifié dans les choix: with INT_A select

Z <= A when 0,

B when 1 to 3,

C when 4|6|8,

D when others;

Comme l’instruction case les choix ne doivent pas se recouvrir: with INT_A select

Z <= A when 0,

B when 1 to 3,

C when 2|6|8, --

'X' when others;

Comme l’instruction case il n’y a pas de priorité implicite dans les choix: architecture COND of BYTE is

type BYTE_POS is (LOWER, UPPER);

signal SEL: BYTE_POS;

begin

with SEL select

OBUS <= REG(0 to 7) when LOWER,

REG(8 to 15) when UPPER;

end COND;

Les expressions peuvent être associées à des délais. Le mode de delai Transport doit être spécifié.

Effets sur la synthèse

Les selected signal assignments sont synthésisables.

Une assignation à 'Z' will génére une source 3-états..



  Sequential Signal Assignmentretour en HAUT Le Sequential Signal Assignment est une variété d’instruction séquentielle. Qui peut être utilisée dans un process ou une procedure.

Syntaxe : signal_name <= expression;

signal_name <= expression after delay; Règles et Exemples

Un sequential signal assignment prend effet lorsque le process est suspendu. Si il y a plus d’une assignation à un même signal avant la suspension, c’est la dernière assignation qui agira:

Si un signal est assigné dans un process et s’il est dans la sensitivity list, il re-active le process :

architecture EX1 of V is

signal A,B,M,N,Y,Z : integer;

begin

process (A, B, M, N)

begin

M <= A;

N <= B;

Z <= M + N;

M <= 2*A;

Y <= M + N;

end process;

end EX1;

Dans cette architecture les signaux Y et Z prendrons la même valeur (2*A + B) car le signal M est assigné deux fois, la première sera surchargée par la seconde.

Un sequential signal assignment peut avoir un délai:

process (A,B)

begin

SUM <= A xor B after 1.7 ns;

CARRY <= A and B after 1.2 ns;

end process;

Effets sur la synthèse

Le sequential signal assignments est synthésisable.


Subtype Declarationretour en HAUT Une Subtype Declaration est utilisable dans un package, une entity, une architecture, un process, une procedure ou une function.

Syntaxe : subtype subtype_name is base_type range range_constraint;

Règles et Exemples

Les assignations ne peuvent pas être faites entre objets de types différents.

type BUS_VAL is range 0 to 255;

type MY_LOGIC is ('0','1');

variable X_INT : integer := 22;

variable X_BUS : BUS_VAL := 22;

variable X_BIT : bit := '0';

variable X_MY : MY_LOGIC := '0';

X_BUS := X_INT; --

X_MY := X_BIT; --

Comme subtype est du même type que son type de base, Les assignations les assignations entre subtype et type de base se font sans conversion: subtype BUS_VAL is integer range 0 to 255;

subtype MY_LOGIC is std_ulogic range 'X' to 'Z';

variable X_INT : integer := 22;

variable X_BUS : BUS_VAL;

variable X_STD : std_ulogic := '0';

variable X_MY : MY_LOGIC;

X_BUS := X_INT; --

X_MY := X_STD; --

Les Subtypes natural et positive sont des subtypes pré définis du type integer subtype NATURAL is integer range 0 to integer'high;

subtype POSITIVE is integer range 1 to integer'high;

Le package std_logic_1164 définit les subtypes de std_ulogic: subtype XO1 is std_ulogic range 'X' to '1';

subtype XO1Z is std_ulogic range 'X' to 'Z';

subtype UXO1 is std_ulogic range 'U' to '1';7

Effets sur la synthèse

La plupart des outils acceptent les subtypes.


Type Conversionretour en HAUT Le Type Conversion est une variété d’expression, utilisable dans un package, une entity, une architecture, un process, une procedure ou une function.

Syntaxe : target_type (closely_related_expression) conversion_function (expression)

Règles et Exemples

Les objets dont le type est défini par l’utilisateur ne peuvent pas être assigné par des objects de types proches. Une conversion de type permet l’assignation:

type BUS_VAL is range 0 to 255;

variable X_INT : integer := 22;

variable X_BUS : BUS_VAL;

X_BUS := X_INT; --

X_BUS := BUS_VAL(X_INT);

Les types proches sont:

1) les types integer et real,

(2) les types tableau dont les longueurs, les indices et les éléments correspondent:

type T_BYTE is array (7 downto 0) of std_ulogic;

signal TYPE_BUS : T_BYTE;

signal VEC_BUS : std_ulogic_vector (7 downto 0);

...

TYPE_BUS <= VEC_BUS; --

TYPE_BUS <= T_BYTE(VEC_BUS);

Si une conversion est nécessaire entre deux types qui ne sont pas proches, une fonction de conversion définie par l’utilisateur sera utilisée : signal X_BOOL: boolean;

signal X_STD: std_ulogic;

function BOOL_TO_SL(X : boolean) return std_ulogic is

begin

if X then return '1';

else return '0';

end if;

end BOOL_TO_SL;

...

X_STD <= X_BOOL; --

X_STD <= BOOL_TO_SL(X_BOOL);

Une fonction de type-conversion doit être appelée pour une association de port, pour faire correspondre un port type à un signal type.

Effets sur la synthèse

La plupart des outils accèptent les type conversion.

La plupart des outils acceptent les fonctions du package std_logic_1164.


Type Declarationretour en HAUT Une Type Declaration est utilisable dans un package, une entity, une architecture, un process, une procedure ou une function.

Syntaxe : type type_name is type_definition;

Règles et Exemples

Les types scalaires ne mémorise qu’une seule valeur. Les types scalaires pré définis sont integer, real, bit, boolean et character. Des types numériques définis par l’utilisateur sont ainsi déclarés:

type T_INT is range 0 to 9;

type T_REAL is range -9.9 to 9.9;

type BUS_VAL is range 0 to 255;

type MY_STATE is (RESET,IDLE,ACKA);

type MY_LOGIC is ('X','0','1','Z');

Les types composite (arrays et records) mémorise plus d’une valeur. type T_PACKET is record

BYTE_ID: std_ulogic;

PARITY : std_ulogic;

ADDRESS: integer range 0 to 3;

DATA : std_ulogic_vector (3 downto 0);

end record;

Les objets de type record sont assignés à l’aide d’aggregates. signal TX_DATA : T_PACKET;

...

TX_DATA.ADDRESS <= 3;

Les autres types doivent être déclarés comme type fichier, type access et types physique.

Les types physique permettent de décrires des unités physique comme, tension, température, etc. Le type pré défini time est type physique, il peut s’exprimer avec les unités suivantes:

fs (femtosecond)  ms (millisecond)

ps (picosecond)  sec (second)

ns (nanosecond)  min (minute)

us (microsecond)  hr (hour)

Effets sur la synthèse

La plupart des outils acceptent les types: integer, boolean, bit, bit_vector, les types std_logic_1164.


Use Clauseretour en HAUT La Clause Use est une clause de contexte qui est applicable dans un package, une entity, une architecture,une configuration.

Syntaxe : use library_name.primary_unit_name;

use library_name.primary_unit_name.item; Règles et Exemples

La clause use doit apparaître avant le début de la description. Si l’unité à utiliser n’est pas dans la librairie work, la clause library doit la précéder:

library IEEE;

use IEEE.STD_LOGIC_1164.all;

entity WIDGET is

-- etc.

end WIDGET;

La clause use n’est valide que pour la design unit qui la suit immédiatement dans le fichier. elle est automatiquement appliquée à toute secondary units associée à la primary units pour laquelle elle est valide.

Lorsque plusieurs primary design units dans le même fichier utilisent les mêmes librairies il faut répéter la clause use avant chacune d’elles.

Le dernier champ de la clause use peut être remplacer par all, pour accéder tout les élément du design unit, ou toutes les design units d’une librairie:

library MY_LIB;

use MY_LIB.MY_PACK.all;

Dans une a configuration: library ASIC_LIB;

configuration ASIC_TECH of ENT is

for GATE_ARCH

use ASIC_LIB.all;

end for;

end ASIC_TECH;

Effets sur la synthèse

La plupart des outils acceptent la clause use.


Variable Assignmentretour en HAUT Une Variable Assignment est une instruction séquentielle qui peut être utilisée dans un process, une procedure, ou une function.

Syntaxe : variable_name := expression;

Règles et Exemples

process (A, B, C, SEL)

variable X : integer range 0 to 7;

begin

if SEL = '1' then X := B;

else X := C;

end if;

Z <= A + X;

end process;

Une assignation de variable prend effet immédiatement: architecture EX1 of V is

signal A,B,Y,Z : integer;

begin

process (A, B)

variable M, N : integer;

begin

M := A;

N := B;

Z <= M + N;

M := 2*A;

Y <= M + N;

end process;

end EX1;

Une assignation de variable ne peut pas avoir de délai.

Une variable, dans un process peut se comporter comme un registre, elles conservent leurs valeurs entre deux activation du process:

process (CLK)

variable Q : std_ulogic;

begin

if CLK'event and CLK='1' then

PULSE <= D and not(Q);

Q := D;

-- PULSE and Q act as registers

end if;

end process;

Effets sur la synthèse

La plupart des outils acceptent les assignations de variable.

Les variables déclrées dans un sous programme sont synthésisées par de la logique combinatoire.


Variable Declaration Une Declaration de Variable est utilisable dans un process, une procedure une function.

Syntaxe : variable variable_name : type;

variable variable_name : type := initial_value; Règles et Exemples variable HEIGHT : integer := 8;

variable COND : boolean := true;

variable IN_STRING : string(1 to 80);

variable M,N : bit := '1';

variable I : integer range 0 to 3;

variable MAKE_FRAME_STATE : T_MAKE_FRAME_STATE := RCV_HIGH;

Une variable peut avoir une valeur initiale explicite lorsqu’elle est déclarée. Si elle n’en n’a pas, elle est initialisée par défaut à la plus petite valeur ('left) du type déclaré: variable I : integer range 0 to 3;

-- initial value of I is 0

variable X : std_ulogic;

-- initial value of X is 'U'

Les variables dans les sous programmes (functions et procedures) sont initialisées chaque fois que le sous programme est appelé : function PARITY (X : std_ulogic_vector) return std_ulogic is

variable TMP : std_ulogic := '0';

begin

for J in X'range loop TMP := TMP xor X(J);

end loop; --no need to initialise TMP

return TMP;

end PARITY;

Les variables dans les processes, hormis pour "FOR LOOP", sont initialisées au début de la simulation (time = 0 nS) process (A)

variable TMP : std_ulogic := '0';

begin

TMP := '0';

-- in this example we need to reset

-- TMP to '0' each time the process

-- is activated

for I in A'low to A'high loop TMP := TMP xor A(I);

end loop;

ODD <= TMP;

end process;

Effets sur la synthèse

La plupart des outils acceptent les variables.

Les variables déclrées dans un sous programme sont synthésisées par de la logique combinatoire.


Wait Statementretour en HAUT Le Wait Statement est une instruction sequentielle, utilisable dans un process ou une procedure.

Syntaxe : wait until condition;

wait on signal_list;

wait for time;

wait;

Règles et Exemples

L’instruction wait until suspend un process jusqu'à ce qu’un changement survienne sur l’un des signaux et que la condition devienne vraie. Un front montant sur NET_DATA_VALID et 3 fronts montants sur CLK sont nécessaire pour que le process soit effectué:

L’attribut 'event paraît redondant, mais beaucoup d’outils de synthèse en ont besoin:

WAIT_PROC: process

begin

wait until CLK'event and CLK='1';

Q1 <= D1;

end process;

L’instruction wait on équivalente à une sensitivity list. Ces processes sont identiques:

process (A,B)

begin

-- sequential statements

end process;
 
 

Wait for et wait sont utilisés dans les modèles comportementaux et dans les test benches. STIMULUS: process

begin

EN_1 <= '0';

EN_2 <= '1';

wait for 10 ns;

EN_1 <= '1';

EN_2 <= '0';

wait for 10 ns;

EN_1 <= '0';

wait for 10 ns;

wait; -- end of test

end process STIMULUS;

L’instruction wait ne peut pas être utilisée: (1) dans un process avec une sensitivity list,

(2) dans une procedure appelée par un process avec une sensitivity list,

(3)dans un function, ou une procedure appélée par une function.

Effets sur la synthèse

La plupart des outils ne supporte que l’instruction wait until.


While and Infinite Loopretour en HAUT Les boucles While et Infinite Loops sont des instructions sequentielles utilisables dans un process, une function ou une procedure.

Syntaxe : while condition loop

sequential statements

end loop;

loop

sequential statements

end loop;

Règles et Exemples

La boucle while répète la séquence d’instructiond si la condition est vraie. La condition est testée avant chaque itération:

process (A)

variable I : integer range 0 to 4;

begin

Z <= "0000";

I := 0;

while (I <= 3) loop

if (A = I) then Z(I) <= '1';

end if;

I := I + 1;

end loop;

end process;

Les boucles while sont utilisées dans les test benches: process

begin

while NOW < MAX_SIM_TIME loop

CLK <= not CLK ;

wait for PERIOD/2;

end loop;

wait;

end process; retour en HAUT

Pour éviter les blocages pendant la simulation, une boucle infinie doit contenir comme dernière instruction, une instruction wait ou exit: process (A)

variable I : integer range 0 to 4;

begin

Z <= "0000";

I := 0;

L1: loop

exit L1 when I = 4;

if (A = I) then Z(I) <= '1';

end if;

I := I + 1;

end loop;

end process;

Effets sur la synthèse

Les boucles while et infinite loops sont supportées par les outils de synthèse.


retour en HAUT
Menu Général